#ifndef _RINGBUFFER_H
#define _RINGBUFFER_H
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
namespace sjl {
#define MIN(a, b) ((a < b) ? a : b)
#define MAX(a, b) ((a > b) ? a : b)
class ringbuffer
{
  private:
    char *   _buffer;
    uint32_t _size; // buffer size
    uint32_t _in;   // write pos
    uint32_t _out;  // read pos
    //返回大于size的最小2的次方
    uint32_t round_up_pow_of_two(uint32_t size)
    {
        int      n = 0;
        uint32_t t = size;
        while (0 != t)
        {
            t /= 2;
            ++n;
        }
        return 1 << n;
    }

  public:
    explicit ringbuffer(uint32_t size) : _in(0), _out(0)
    {
        if (size & (size - 1))
        {
            size = round_up_pow_of_two(size);
        }
        _size   = size;
        _buffer = static_cast<char *>(malloc(_size));
    }

    ~ringbuffer()
    {
        free(_buffer);
    }
    uint32_t put(char *buffer, uint32_t len)
    {
        len        = MIN(len, _size - _in + _out);          //写入长度不能大于可写长度
        uint32_t l = MIN(len, _size - (_in & (_size - 1))); //& 用来防止溢出
        //_in -> end
        memcpy(_buffer + (_in & (_size - 1)), buffer, l);
        // begin -> remain
        memcpy(_buffer, buffer + l, len - l);

        _in += len; //可能会溢出，大于_size
        return len;
    }
    uint32_t get(char *buffer, uint32_t len)
    {
        len        = MIN(len, _in - _out); //在put时没有做溢出处理。所以_in始终大于_out
        uint32_t l = MIN(len, _size - (_out & (_size - 1)));
        // out -> end
        memcpy(buffer, _buffer + (_out & (_size - 1)), l);
        // buffer -> remain
        memcpy(buffer + l, _buffer, len - l);
        _out += len;
        return len;
    }
    uint32_t size() const
    {
        return _size;
    }
    uint32_t count() const
    {
        return _in - _out;
    }
};

} // namespace sjl

#endif // _RINGBUFFER_H
